﻿using DataAccessObjectLayer;
using ModelLayer;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;

namespace ControllerLayer
{
    /// <summary>
    ///
    /// </summary>
    public class RouteCtr : IRouteCtr
    {
        /// <summary>
        /// Generates a route using Dijkstra's graph search algorithm.
        /// </summary>
        /// <param name="startStation">The start station.</param>
        /// <param name="endStation">The end station.</param>
        /// <returns>Route.</returns>
        public Route GenerateRouteUsingDijkstras(Station startStation, Station endStation)
        {
            var route = new Route { StartStation = startStation, EndStation = endStation, PartRoutes = new List<PartRoute>(), Id = -1 };
            //Add route to customer.
            var stationCtr = new StationCtr();
            var graph = new Dijkstras.Graph(GetStationsAsNodes(stationCtr.GetAllStation()), stationCtr.GetAllEdges());
            route.PartRoutes = graph.MinDistancePath(route.StartStation, route.EndStation).ToList();
            return route;
        }

        public Route GenerateRouteUsingAStar(Station startStation, Station endStation)
        {
            var route = new Route { StartStation = startStation, EndStation = endStation, PartRoutes = new List<PartRoute>(), Id = -1 };
            //Add route to customer.
            var stationCtr = new StationCtr();
            var graph = new AStar.Graph(GetStationsAsNodes(stationCtr.GetAllStation()), stationCtr.GetAllEdges());
            route.PartRoutes = graph.MinDistancePath(route.StartStation, route.EndStation).ToList();
            return route;
        }

        /// <summary>
        /// Get a collection of stations as nodes instead.
        /// </summary>
        /// <param name="stationsList">The stations list.</param>
        /// <returns>List{Node}.</returns>
        private List<Node> GetStationsAsNodes(IEnumerable<Station> stationsList)
        {
            return stationsList.Select(station => new Node(station)).ToList();
        }

        /// <summary>
        /// Removes a route from the database.
        /// </summary>
        /// <param name="routeId">The identifier.</param>
        /// <returns>The number of affected rows</returns>
        public int RemoveRoute(long routeId)
        {
            DBRoute dbRoute = new DBRoute();
            return dbRoute.RemoveRoute(routeId);
        }

        /// <summary>
        /// Creates a route in the database.
        /// </summary>
        /// <param name="route">The route.</param>
        /// <param name="con">The current connection being used</param>
        /// <param name="transaction">the current transaction being used by DBReservation</param>
        /// <returns>The number of affected rows</returns>
        public int CreateRoute(Route route, SqlConnection con, SqlTransaction transaction)
        {
            DBRoute dbRoute = new DBRoute();
            return dbRoute.InsertRoute(route, con, transaction);
        }

        /// <summary>
        /// Gets a route from the database.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>Route.</returns>
        public Route GetRoute(long id)
        {
            DBRoute dbRoute = new DBRoute();
            return dbRoute.GetRoute(id);
        }
    }
}